﻿using System.Linq;
using AB.ServiceDirectory.Commons.DataFilters;
using AB.ServiceDirectory.Entities;

namespace AB.ServiceDirectory.Dao
{
    public class PremiseDao
    {
        private readonly ServicesDirectoryDataContext _context = DB.Context;

        public IQueryable<Premise> GetList(PremiseFilter filter, string sortType, int startRowIndex, int max)
        {
            IQueryable<Premise> data = from p in _context.Premises
                                       select p;

            // 1. Filter by condition
            if (filter != null)
            {
                data = GetListQuery(data, filter);
            }

            // 2. Sorting
            data = GetListSort(data, sortType);

            // 3. Limit the rows
            data = data.Skip(startRowIndex).Take(max);

            return data;
        }

        private static IQueryable<Premise> GetListSort(IQueryable<Premise> data, string sortType)
        {
            bool sortDescending = false;
            if (!string.IsNullOrEmpty(sortType))
            {
                string[] values = sortType.Split(' ');
                sortType = values[0];

                if (values.Length > 1)
                {
                    sortDescending = (values[1] == "DESC");
                }

                switch (sortType)
                {
                    case "LocationName":
                        data = sortDescending
                                   ? data.OrderByDescending(g => g.LocationName)
                                   : data.OrderBy(g => g.LocationName);
                        break;
                    case "AddressLine":
                        data = sortDescending
                                   ? data.OrderByDescending(g => g.Address.AddressLine)
                                   : data.OrderBy(g => g.Address.AddressLine);
                        break;
                    case "Postcode":
                        data = sortDescending
                                   ? data.OrderByDescending(g => g.Address.Postcode)
                                   : data.OrderBy(g => g.Address.Postcode);
                        break;
                    default:
                        data = sortDescending
                                   ? data.OrderByDescending(g => g.PremiseId)
                                   : data.OrderBy(g => g.PremiseId);
                        break;
                }
            }

            return data;
        }

        private IQueryable<Premise> GetListQuery(IQueryable<Premise> data, PremiseFilter filter)
        {
            // Filter by unassociated service id
            if (filter.UnassociatedServiceId > 0)
            {
                var associatedPremiseIds = (from s in _context.ServicePremises
                                            where s.ServiceId == filter.UnassociatedServiceId
                                            select s.PremiseId).ToList();

                data = data.Where(s => !associatedPremiseIds.Contains(s.PremiseId));
            }

            // Filter by beginning of the letters
            if (filter.BeginningLetters != null)
            {
                data = data.Where(g => filter.BeginningLetters.Contains(g.PremiseName[0].ToString()));
            }

            // Filter by location name
            if (!string.IsNullOrEmpty(filter.LocationName))
            {
                data = data.Where(s => s.LocationName.Contains(filter.LocationName));
            }

            // Filter by in-active & active Gor
            if (!filter.IncludeInactive)
            {
                data = data.Where(g => g.IsActive == !filter.IncludeInactive);
            }

            return data;
        }

        public int GetListCount(PremiseFilter filter)
        {
            IQueryable<Premise> data = from p in _context.Premises
                                       select p;

            return GetListQuery(data, filter).Count();
        }

        public Premise GetPremiseById(int id)
        {
            Premise premise = _context.Premises.FirstOrDefault(g => g.PremiseId == id);
            return premise;
        }

        /// <summary>
        /// Adds the premise.
        /// </summary>
        /// <param name="premise">The premise.</param>
        /// <returns></returns>
        public bool AddPremise(Premise premise)
        {
            return true;
        }

        public bool EditPremise(Premise premise)
        {
            return true;
        }

        public void SetPremiseStatus(int premiseId, bool status)
        {
            
        }
    }
}